package cn.ipenta.app.service;

import cn.ipenta.app.controller.vo.CirculationVo;
import cn.ipenta.app.controller.vo.InoculationVo;
import cn.ipenta.blockchain.BlockChainException;
import cn.ipenta.blockchain.PropertiesConfigurator;
import cn.ipenta.blockchain.entity.Message;
import cn.ipenta.blockchain.entity.RecordInfo;
import cn.ipenta.blockchain.entity.TransactionInfo;
import cn.ipenta.blockchain.repo.BlockChainClient;
import cn.ipenta.blockchain.utils.TimeUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author ipenta
 * @ClassName: VaccineService
 * @Description: TODO
 * @date 2017-09-21 下午5:05
 */
@Service
public class VaccineService {

	private static final Logger logger = LoggerFactory.getLogger(VaccineService.class);

	private static final String CIRCULATIONS = "circulations";
	private static final String INOCULATIONS = "inoculationz";
	private static final String VACCINE_ID = "VACCINE_ID";

	@Autowired
	BlockChainClient blockChainClient;

	@Autowired
	private PropertiesConfigurator propertiesConfigurator;


	/**
	 *记录流通交易
	 *
	 * */
	public Boolean recordCirculation(CirculationVo circulationVo) {
		Map<String, String> result = JSONObject.parseObject(JSON.toJSONString(circulationVo), new TypeReference<Map<String, String>>() {
		});

		if (null != createRecord(CIRCULATIONS, result))
			return Boolean.TRUE;

		return Boolean.FALSE;

	}

	/**
	 *记录接种交易
	 *
	 * */
	public Boolean recordInoculation(InoculationVo inoculationVo) {
		Map<String, String> result = JSONObject.parseObject(JSON.toJSONString(inoculationVo), new TypeReference<Map<String, String>>() {
		});

		if (null != createRecord(INOCULATIONS, result))
			return Boolean.TRUE;

		return Boolean.FALSE;
	}

	/**
	 *查询记录
	 *
	 * */
	public List<TreeMap<String,Object>> findRecord(String vaccineId) {
		List<TreeMap<String,Object>> treeMapList = new ArrayList<>();

		Map<String,String> filter = new HashMap<>();
		filter.put(VACCINE_ID,vaccineId);
		List<TransactionInfo> inoculations = messageConverter(blockChainClient.lookupTxByKey(INOCULATIONS, filter));
		List<TransactionInfo> circulations = messageConverter(blockChainClient.lookupTxByKey(CIRCULATIONS, filter));
		inoculations.addAll(circulations);
		for (TransactionInfo transactionInfo: inoculations){
			RecordInfo recordInfo =  transactionInfo.getContentInfo();
			treeMapList.add(recordInfo.getRecordContent());
		}

		return treeMapList;
	}

	private String createRecord(String txType, Map<String, String> map) throws BlockChainException {
		return createRecord(txType, map, null, new ArrayList<String>());
	}

	private String createRecord(String txType, Map<String, String> map, String referTxHash) throws BlockChainException {
		return createRecord(txType, map, referTxHash, new ArrayList<String>());
	}

	private String createRecord(String txType, Map<String, String> map, String referTxHash, List<String> authorizedUpdaters)
			throws BlockChainException {

		String archiveHash = "000000000000";

		long timestamp = TimeUtils.getTxTimestamp();
		String public_key = propertiesConfigurator.getPublicKey();
		String private_key = propertiesConfigurator.getPrivateKey();
		String sign = messageConverter(
				blockChainClient.sign2(txType, map, timestamp, referTxHash, authorizedUpdaters, private_key));
		archiveHash = messageConverter(
				blockChainClient.archive2(txType, map, timestamp, public_key, sign, referTxHash, authorizedUpdaters));
		return archiveHash;
	}


	// 数据转换
	private <T> T messageConverter(Message<T> message) {
		if (message.getStatus().equals(Message.Status.SUCCESS.getValue())) {
			return message.getData();
		} else {
			throw new BlockChainException(message.getErrorContent());
		}
	}



}
